// Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
#include <iostream>
#include <vector>
#include <chrono>
#include <thread>

#include "acl/acl.h"
#include "acl/acl_op_compiler.h"
#include "graph/operator_reg.h"

#define CALL_RT(x)                                                                                                     \
    if (auto ret = (x) != 0) {                                                                                         \
        std::cout << "[ERROR] Failed to exec acl api " << #x << ", result: " << ret << std::endl;                      \
        return -1;                                                                                                     \
    } else {                                                                                                           \
        std::cout << "[INFO] Succeeded to exec acl api " << #x << std::endl;                                           \
    }

#define LOG_INFO(FMT, ...) printf("[INFO] " FMT "\n", __VA_ARGS__)

int main()
{
    // init acl
    CALL_RT(aclInit(nullptr));
    CALL_RT(aclrtSetDevice(0));

    aclrtStream stream;
    CALL_RT(aclrtCreateStream(&stream));

    std::vector<aclTensorDesc *> inputDescs;
    std::vector<aclDataBuffer *> inBuffers;
    std::vector<aclTensorDesc *> outputDescs;
    std::vector<aclDataBuffer *> outBuffers;

    //  todo fill inputDescs outputDescs inBuffers outBuffers

    // compile and execute op
    CALL_RT(aclopSetCompileFlag(ACL_OP_COMPILE_FUZZ));
    CALL_RT(aclopCompileAndExecuteV2("Relu7", inputDescs.size(), inputDescs, inBuffers.data(), outputDescs.size(),
                                     outputDescs, outBuffers.data(), nullptr, ACL_ENGINE_SYS, ACL_COMPILE_SYS, NULL,
                                     stream));

    // run offline model op
    CALL_RT(aclopSetModelDir("op_models"));
    CALL_RT(aclopExecuteV2("Relu7", 1, inputDescs, inBuffers.data(), 1, outputDescs,
        outBuffers.data(), nullptr, stream));

    CALL_RT(aclrtSynchronizeStream(stream));

    std::vector<int> outputHost(len, 0);
    CALL_RT(aclrtMemcpy(outputHost.data(), len * sizeof(int), outputDevice, len * sizeof(int),
        ACL_MEMCPY_DEVICE_TO_HOST));
}
